package cn.blossoming.service.video.impl;

import cn.blossoming.dao.domain.*;
import cn.blossoming.service.base.SessionService;
import cn.blossoming.service.base.exception.ServiceException;
import cn.blossoming.service.base.impl.BaseServiceImpl;
import cn.blossoming.service.dto.User;
import cn.blossoming.service.dto.Video;
import cn.blossoming.service.dto.VideoComment;
import cn.blossoming.service.video.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class VideoServiceImpl extends BaseServiceImpl<VideoEntity, Integer> implements VideoService, SessionService {

    @Autowired
    private VideoPraiseService videoPraiseService;
    @Autowired
    private VideoCommentService videoCommentService;
    @Autowired
    private VideoReadService videoReadService;
    @Autowired
    private VideoCommentPraiseService videoCommentPraiseService;


    @Override
    public List<Video> findPage(PageRequest pageRequest) {
        Page<VideoEntity> page = this.findAll(pageRequest);
        UserEntity currentUserEntity = UserEntity.builder().id(getCurrentUserId()).build();
        return page.getContent().stream().map(entity -> {
            Video video = new Video(entity);
            UserEntity userEntity = entity.getUser();
            video.setUser(User.builder().name(userEntity.getName()).avatar(userEntity.getAvatar()).build());
            video.setPraise(videoPraiseService.exists(Example.of(VideoPraiseEntity.builder().user(currentUserEntity).video(entity).build())));
            return video;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public Video getVideoById(int id) {
        VideoEntity videoEntity = this.findOne(id);
        VideoReadEntity readEntity = VideoReadEntity.builder().user(UserEntity.builder().id(getCurrentUserId()).build()).build();
        if (!videoReadService.exists(Example.of(readEntity))) {
            readEntity.setVideo(videoEntity);
            videoReadService.save(readEntity);
            videoEntity.setReadNum(videoEntity.getReadNum() + 1);
            this.save(videoEntity);
        }

        Video video = new Video(videoEntity);
        video.setUser(new User(videoEntity.getUser()));
        video.setMyself(getCurrentUserId().equals(video.getUser().getId()));
        video.setPraise(videoPraiseService.exists(Example.of(VideoPraiseEntity.builder().user(UserEntity.builder().id(getCurrentUserId()).build()).video(videoEntity).build())));
        List<VideoComment> comments = getCommentsByVideoId(video.getId(), new PageRequest(1, 10, Sort.Direction.DESC, "id"));
        video.setVideoComments(comments);
        video.setVideoTags(videoEntity.getVideoTags());
        return video;
    }

    @Override
    @Transactional
    public Video praiseVideo(int id) {
        VideoPraiseEntity praise = new VideoPraiseEntity();
        praise.setUser(UserEntity.builder().id(getCurrentUserId()).build());
        praise.setVideo(VideoEntity.builder().id(id).build());
        if (videoPraiseService.exists(Example.of(praise)))
            throw new ServiceException(420, "你已经赞过了");
        videoPraiseService.save(praise);
        VideoEntity videoEntity = this.findOne(id);
        videoEntity.setPraiseNum(videoEntity.getPraiseNum() + 1);
        this.save(videoEntity);
        Video video = new Video(videoEntity);
        video.setUser(new User(videoEntity.getUser()));
        video.setMyself(getCurrentUserId().equals(video.getUser().getId()));
        return video;
    }

    @Override
    public List<VideoComment> getCommentsByVideoId(int id, PageRequest pageRequest) {
        Page<VideoCommentEntity> page = videoCommentService.findAll(Example.of(VideoCommentEntity.builder().video(VideoEntity.builder().id(id).build()).build()), pageRequest);
        List<VideoComment> comments = Video.videoEntityComments2VideoComments(page.getContent());
        Integer userId = getCurrentUserId();
        comments.forEach(comment -> comment.setPraise(videoCommentPraiseService.exists(Example.of(VideoCommentPraiseEntity.builder().videoComment(VideoCommentEntity.builder().id(comment.getId()).build()).user(UserEntity.builder().id(userId).build()).build()))));
        return comments;
    }

    @Override
    @Transactional
    public void videoCommentPraise(int id) {
        VideoCommentEntity entity = videoCommentService.findOne(id);
        VideoCommentPraiseEntity praiseEntity = new VideoCommentPraiseEntity();
        praiseEntity.setUser(UserEntity.builder().id(getCurrentUserId()).build());
        praiseEntity.setVideoComment(entity);
        if (videoCommentPraiseService.exists(Example.of(praiseEntity)))
            throw new ServiceException(420, "你已经赞过了");

        videoCommentPraiseService.save(praiseEntity);
        entity.setCommentNum(entity.getCommentNum() + 1);
        videoCommentService.save(entity);
    }

    @Override
    @Transactional
    public void addVideoComment(int id, String content) {
        VideoEntity entity = this.findOne(id);
        entity.setCommentNum(entity.getCommentNum() + 1);
        this.save(entity);
        VideoCommentEntity videoComment = new VideoCommentEntity();
        videoComment.setVideo(entity);
        videoComment.setUser(UserEntity.builder().id(getCurrentUserId()).build());
        videoComment.setContent(content);
        videoCommentService.save(videoComment);
    }

    @Override
    @Transactional
    public void addVideoCommentComment(int commentId, String content, int videoId) {
        VideoEntity entity = this.findOne(videoId);
        entity.setCommentNum(entity.getCommentNum() + 1);
        this.save(entity);

        VideoCommentEntity one = videoCommentService.findOne(commentId);
        one.setCommentNum(one.getCommentNum() + 1);

        VideoCommentEntity videoComment = new VideoCommentEntity();
        videoComment.setVideoComment(one);
        videoComment.setVideo(VideoEntity.builder().id(0).build());
        videoComment.setUser(UserEntity.builder().id(getCurrentUserId()).build());
        videoComment.setContent(content);
        videoCommentService.save(one);
        videoCommentService.save(videoComment);
    }

    @Override
    public List<VideoComment> getVideoCommentCommentByCommentId(int commentId, PageRequest pageRequest) {
        VideoCommentEntity parent = VideoCommentEntity.builder().id(commentId).build();
        Page<VideoCommentEntity> page = videoCommentService.findAll(Example.of(VideoCommentEntity.builder().videoComment(parent).build()), pageRequest);
        List<VideoComment> comments = Video.videoEntityComments2VideoComments(page.getContent());
        UserEntity currentUserEntity = UserEntity.builder().id(getCurrentUserId()).build();
        comments.forEach(comment -> {
            comment.setPraise(videoCommentPraiseService.exists(Example.of(VideoCommentPraiseEntity.builder().videoComment(VideoCommentEntity.builder().id(comment.getId()).build()).user(currentUserEntity).build())));
        });
        return comments;
    }

    @Override
    public List<Video> findPageByUser(int userId, PageRequest pageRequest) {
        Integer currentUserId = getCurrentUserId();
        UserEntity currentUserEntity = UserEntity.builder().id(currentUserId).build();
        Page<VideoEntity> page = this.findAll(Example.of(VideoEntity.builder().user(UserEntity.builder().id(userId).build()).build()), pageRequest);
        return page.getContent().stream().map(Video::new).peek(video -> {
            if (currentUserId.equals(userId))
                video.setMyself(true);
            video.setPraise(videoPraiseService.exists(Example.of(VideoPraiseEntity.builder().user(currentUserEntity).video(VideoEntity.builder().id(video.getId()).build()).build())));
        }).collect(Collectors.toList());
    }

}
